import { addClassName, containsClassName, createDiv, h, removeClassName, removeElement } from '../dom';
import './style.css';

function num2px(num) {
  return num + 'px';
}

/**
 * UI所有元素的基类
 */
export default class VuiElement {
  constructor() {
    // css类名
    this._className = {};
    // dom属性值
    this._domAttrs = {};
    // 组件配置项
    this._config = {};
    // 事件
    this._actions = {};
    // 容器
    this.container = null;
    // 是否可见
    this.visible = true;
  }

  /**
   * 创建新实例 并执行initUI函数
   */
  static newInstance(...args) {
    const instance = new this(...args);
    instance.initUI();
    return instance;
  }

  /**
   * 初始化UI
   */
  initUI() {}

  /**
   * 初始化UI
   */
  init() {
    return this;
  }

  /**
   * 合并样式
   * @param {*} className
   * @return {*}
   */
  mergeClassName(className) {
    this._className = Object.assign(this._className, className);
  }

  /**
   * 初始化容器
   */
  initContainer(innerText, title, id) {
    const cls = this._className;
    const disabled = this._config.disabled || this._config.enabled === false;
    const clsContainer = disabled ? cls.container + ' vui-disabled' : cls.container;
    this.container = this.createDiv(clsContainer, innerText, title, id);
  }

  /**
   * 创建div
   * @param {*} className
   * @param {*} innerText
   * @param {*} title
   * @param {*} id
   */
  createDiv(className, innerText, title, id) {
    return createDiv(className, innerText, title, id);
  }

  /**
   * 添加class
   * @param {*} className
   */
  addClass(className) {
    addClassName(this.container, className);
  }

  /**
   * 移除class
   */
  removeClass(className) {
    removeClassName(this.container, className);
  }

  containsClass(className) {
    return containsClassName(this.container, className);
  }

  removeProperty(key) {
    if (this.container) {
      this.container.style.setProperty(key, 'initial');
    }
  }

  setProperty(key, value) {
    if (this.container) {
      this.container.style.setProperty(key, value);
    }
  }

  setContentEditable(enabled) {
    if (this.container) {
      this.container.contentEditable = enabled;
    }
  }

  /**
   * 添加子元素
   * @param {*} child
   */
  append(child) {
    h(this.container, child);
  }

  insertBefore(child, index = 0) {
    if (this.container) {
      let elt = child;
      if (child instanceof VuiElement) {
        elt = child.container;
      }
      this.container.insertBefore(elt, this.container.children[index]);
    }
  }

  /**
   * 移除子元素
   * @param {*} child
   */
  remove(child) {
    this.container?.removeChild(child?.container);
  }

  /**
   * 添加元素到父元素
   * @param {*} parent
   */
  appendTo(parent) {
    h(parent, this.container);
  }

  /**
   * 替换元素
   * @param {*} oldElement
   * @param {*} newElement
   */
  replaceElement(oldElement, newElement) {
    let oldElt = oldElement;
    let newElt = newElement;
    if (oldElement instanceof VuiElement) {
      oldElt = oldElement.container;
    }
    if (newElement instanceof VuiElement) {
      newElt = newElement.container;
    }

    oldElt.parentElement?.replaceChild(newElt, oldElt);
  }

  /**
   * 销毁
   */
  destory() {
    removeElement(this.container);
    this.container = null;
  }

  /**
   * 清空
   */
  clean() {
    if (this.container) {
      this.container.innerHTML = '';
    }
  }

  isHTMLElement() {
    return this.container instanceof HTMLElement;
  }

  /**
   * 初始化事件监听
   */
  initEvents() {
    if (this.isHTMLElement()) {
      const container = this.container;
      const actions = this._actions || {};
      for (const key in actions) {
        const listener = actions[key];
        container.addEventListener(key, listener);
      }
    }
  }

  /**
   * 添加事件
   * @param {*} key
   * @param {*} listener
   */
  addEventListener(key, listener) {
    this.container?.addEventListener(key, listener);
  }

  /**
   * 移除事件
   * @param {*} key
   * @param {*} listener
   */
  removeEventListener(key, listener) {
    this.container?.removeEventListener(key, listener);
  }

  /**
   * 设置宽度
   * @param {*} value
   */
  setWidth(value) {
    if (this.container && !isNaN(value)) {
      this._domAttrs.width = value;
      this.container.style.width = num2px(value);
    }
  }

  /**
   * 获取宽度
   */
  getWidth() {
    const width = this._domAttrs.width || this.width || (this._config && this._config.width) || this.container.offsetWidth || this.container.style.width;
    return parseInt(width);
  }

  /**
   * 设置高度
   * @param {*} value
   */
  setHeight(value) {
    if (this.container && !isNaN(value)) {
      this._domAttrs.height = value;
      this.container.style.height = num2px(value);
    }
  }

  /**
   * 获取高度
   */
  getHeight() {
    const height = this._domAttrs.height || this.height || this.container.offsetHeight || this.container.style.height;
    return parseInt(height);
  }

  /**
   * 设置最大高度
   * @param {*} value
   */
  setMaxHeight(value) {
    if (this.container && !isNaN(value)) {
      this.container.style.maxHeight = num2px(value);
    }
  }

  /**
   * 设置背景颜色
   * @param {*} color
   */
  setBackgroundColor(color) {
    if (this.container && color) {
      this.container.style.backgroundColor = color;
    }
  }

  /**
   * 设置可拖拽
   * @param {*} value
   */
  setDraggable(value) {
    if (this.container && value != null) {
      this.container.draggable = value;
    }
  }

  /**
   * 设置位置
   * @param {*} value
   */
  setTop(value) {
    if (this.container) {
      let top = value;
      if (!isNaN(value)) {
        top = num2px(value);
      }
      this.container.style.top = top;
    }
  }

  /**
   * 设置位置
   * @param {*} value
   */
  setLeft(value) {
    if (this.container && !isNaN(value)) {
      this.container.style.left = num2px(value);
    }
  }

  /**
   * 设置位置
   * @param {*} value
   */
  setRight(value) {
    if (this.container && !isNaN(value)) {
      this.container.style.right = num2px(value);
    }
  }

  /**
   * 设置位置
   * @param {*} top
   * @param {*} left
   */
  setTopLeft(top, left) {
    if (this.container) {
      if (!isNaN(top)) {
        this.container.style.top = num2px(top);
      }
      if (!isNaN(left)) {
        this.container.style.left = num2px(left);
      }
    }
  }

  /**
   * 设置外边距
   * @param {*} value
   */
  setMargin(value) {
    if (this.container) {
      this.container.style.margin = value;
    }
  }

  /**
   * 设置内边距
   * @param {*} value
   */
  setPadding(value) {
    if (this.container) {
      this.container.style.padding = value;
    }
  }

  /**
   * 设置内部文本
   * @param {*} text
   */
  setInnerText(text) {
    if (this.container) {
      this.container.innerText = text;
    }
  }

  /**
   * 显示元素
   */
  show() {
    if (this.container) {
      this.container.style.display = 'block';
    }
    this.visible = true;
  }

  /**
   * 隐藏元素
   */
  hide() {
    if (this.container) {
      this.container.style.display = 'none';
    }
    this.visible = false;
  }

  /**
   * 切换显示/隐藏
   */
  toggle() {
    if (this.visible) {
      this.hide();
    } else {
      this.show();
    }
  }

  setVisible(visible) {
    if (visible) {
      this.show();
    } else {
      this.hide();
    }
  }

  /**
   * 添加点击事件
   * @param {*} listener
   */
  setClickListener(listener) {
    if (this.container && typeof listener === 'function') {
      this.container.onclick = listener;
    }
  }

  /**
   * 添加鼠标进入事件
   * @param {*} listener
   */
  setMouseEnterListener(listener) {
    if (this.container && typeof listener === 'function') {
      this.container.onmouseenter = listener;
    }
  }

  /**
   * 添加鼠标离开事件Leave
   * @param {*} listener
   */
  setMouseLeaveListener(listener) {
    if (this.container && typeof listener === 'function') {
      this.container.onmouseleave = listener;
    }
  }

  /**
   * 添加鼠标进入事件
   * @param {*} listener
   */
  setMouseOverListener(listener) {
    if (this.container && typeof listener === 'function') {
      this.container.onmouseover = listener;
    }
  }

  preventDefault() {
    this.container.onmousedown = evt => {
      evt.preventDefault();
    };
  }

  /**
   * 设置属性
   * @param {*} key
   * @param {*} value
   */
  setAttribute(key, value) {
    if (this.container) {
      this.container.setAttribute(key, value);
    }
  }

  /**
   * 获取属性
   * @param {*} key
   * @param {*} value
   */
  getAttribute(key) {
    if (this.container) {
      return this.container.getAttribute(key);
    }
  }

  /**
   * 设置提示
   * @param {*} title
   */
  setTitle(title) {
    if (this.container) {
      this.container.title = title;
    }
  }

  /**
   * 安全运行函数
   * @param {*} items
   */
  safeRun(func, ...args) {
    if (typeof func === 'function') {
      return func(...args);
    } else {
      return null;
    }
  }
}
